home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / falcon / scrdump / source / scrdump.c < prev    next >
C/C++ Source or Header  |  1995-04-27  |  9KB  |  396 lines

  1. #include <tos.h>
  2. #include <linea.h>
  3. #include <vdi.h>        /* nur für MFDB!! */
  4. #include <stdlib.h>
  5.  
  6. #include "sdump.h"
  7.  
  8. #ifndef GEMDUMP
  9.     extern SCREEN_DUMP dump;
  10. #    define inst        dump.inst
  11. #    define scr_nr    dump.nr
  12. #else
  13.     extern INST inst;
  14.     extern int scr_nr;
  15. #endif
  16.  
  17. /*
  18.     fehlerbehandlung
  19. */
  20. int xerr;
  21.  
  22. int h_error(long err,long z)
  23. {
  24.     if ( err<0L || ((z!=0L)&&(err!=z) ) ) {
  25.         xerr=(int)err;
  26.         if ( err>0l )
  27.             xerr=-1000;
  28.         return 1;
  29.     }
  30.     return 0;
  31. }
  32.  
  33. /*
  34.     gepufferte schreibroutinen
  35. */
  36. int f_id,z;        /* f_id: file-id, z: schreibpostiotion im puffer */
  37. char *w_buf;    /* zeigt auf puffer der grö₧e BUF_SIZE */
  38. static void init_write(char *puffer)
  39. {
  40.     w_buf=puffer;
  41.     z=0;
  42. }
  43.  
  44. static int write_byte(char byte)        /* schreibe ein byte gepuffert */
  45. {
  46.     w_buf[z++]=byte;
  47.     if ( z==BUF_SIZE ) {
  48.         if ( h_error(Fwrite(f_id,BUF_SIZE,w_buf),BUF_SIZE) )
  49.             { Fclose(f_id); return 1; }
  50.         z=0;
  51.     }
  52.     return 0;
  53. }
  54.  
  55.                                         /* schreibe block gepuffert */
  56. static int write_block(long len,char *block)
  57. {
  58. long i;
  59.     for ( i=0; i<len; i++,block++ )
  60.         if ( write_byte(*block) )
  61.             return 1;
  62.     return 0;
  63. }
  64.  
  65.                                         /* schreibe restpuffer & schlie₧e datei */
  66. static int close_write(void)
  67. {
  68.     if ( z!=0 ) {
  69.         if ( h_error(Fwrite(f_id,(long)z,w_buf),(long)z) )
  70.             { Fclose(f_id); return 1; }
  71.         z=0;
  72.     }
  73.     return 0;
  74. }
  75.  
  76.                                         /* schreibe ungepackte daten (für img) */
  77. static int write_upk(int len,char *unpacked)
  78. {            
  79.     if ( write_byte(0x80) || write_byte(len) )
  80.         return 1;
  81.     return write_block(len,unpacked);
  82. }
  83.  
  84. /*
  85.     initialisiere strukturen für xIMG-Datei
  86. */
  87. static void init_img(SAVE_IMG *img,IMG_HEAD *head,MFDB *mfdb,int w,int h,char *line,int llen)
  88. {
  89.     img->line=line;                                /* zeilenbuffer */
  90.     img->pic_line=img->pic_buf=mfdb->fd_addr;    /* bildbuffer */
  91.     img->flag=img->line_nr=0;                    /* laufvariable */
  92.  
  93.     img->bwid=w/8;                                /* ausma₧e */
  94.     if ( w%8 )
  95.         img->bwid++;
  96.     if ( img->bwid>llen/mfdb->fd_nplanes )
  97.         img->bwid=llen/mfdb->fd_nplanes;
  98.     img->hght=h;
  99.  
  100.     img->pic_bwid=mfdb->fd_wdwidth*2;            /* breite der bitmap */
  101.     if ( !mfdb->fd_stand )
  102.         img->pic_bwid*=mfdb->fd_nplanes;
  103.  
  104.     img->plane_size=(long)mfdb->fd_wdwidth*2l*mfdb->fd_h;
  105.  
  106.     img->standard=mfdb->fd_stand;
  107.  
  108.     head->ver_num=0;                            /* dateiheader */
  109.     head->head_len=8;
  110.     head->pat_len=2;
  111.  
  112.     head->pix_wid=0x174;
  113.     head->pix_hght=0x174;
  114.     img->planes=mfdb->fd_nplanes;
  115.  
  116.     head->plane_num=mfdb->fd_nplanes;
  117.     head->pix_num=w;
  118.     if ( w>llen/mfdb->fd_nplanes*8 )
  119.         head->pix_num=llen/mfdb->fd_nplanes*8;
  120.     head->scan_num=h;
  121. }
  122.  
  123. /*
  124.     lese/vergleiche zeile
  125. */
  126. static int get_line(SAVE_IMG *img,int mode)
  127. {
  128. char *h1,*h2;
  129. int cnt,i,ii;
  130.  
  131.     if ( img->flag==-1 || (img->flag && mode) )
  132.         return 0;
  133.  
  134.     h1=img->line;
  135.  
  136.     if ( !img->standard ) {                /* st-screen format */
  137.       int offset;
  138.         if ( mode ) {    /* nur testen */
  139.             for ( i=0,offset=0; i<img->planes; i++,offset+=2 ) {
  140.                 for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; h2+=2*(img->planes-1) )
  141.                     for ( ii=0; ii<2 && cnt<img->bwid; ii++,cnt++ )
  142.                         if ( *h1++!=*h2++ )
  143.                             return 0;
  144.             }
  145.         }
  146.         else {            /* kopieren */
  147.             for ( i=0,offset=0; i<img->planes; i++,offset+=2 ) {
  148.                 for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; h2+=2*(img->planes-1) )
  149.                     for ( ii=0; ii<2 && cnt<img->bwid; ii++,cnt++ )
  150.                         *h1++=*h2++;
  151.             }
  152.             img->flag=0;
  153.         }
  154.     }
  155.     else {                                /* standard format */
  156.       long offset;
  157.         if ( mode ) {    /* nur testen */
  158.             for ( i=0,offset=0l; i<img->planes; i++,offset+=img->plane_size ) {
  159.                 for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; cnt++ )
  160.                     if ( *h1++!=*h2++ )
  161.                     return 0;
  162.             }
  163.         }
  164.         else {            /* kopieren */
  165.             for ( i=0,offset=0l; i<img->planes; i++,offset+=img->plane_size ) {
  166.                 for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; cnt++ )
  167.                     *h1++=*h2++;
  168.             }
  169.             img->flag=0;
  170.         }
  171.     }
  172.  
  173.     img->pic_line+=img->pic_bwid;
  174.     img->line_nr++;
  175.     if ( img->line_nr==img->hght ) {    /* ende erreicht */
  176.         img->flag=-1;
  177.     }
  178.     return 1;
  179. }
  180.  
  181. /*
  182.     schreibe block (0,0,wid,hght) aus 'buffer' in xIMG-Datei 'name'
  183.     'col' zeigt auf farbtabelle, 'xflag' gibt an ob IMG (xflag=0) oder xIMG (xflag!=0)
  184.     geschrieben werden soll (falls xflag==0 ist col redundand und wird nicht beachtet)
  185.  
  186.     falls GEMDUMP nicht (mit -DGEMDUMP) in den compileroptionen gesetzt ist
  187.     wird bei gesetztem xflag und 'col==0l' statt der farbtabelle in col
  188.     die farben via xbios ermittelt und geschrieben!
  189.  
  190.     rückgabewert: 0 ok
  191.                   <0 gemdos/bios fehlernummer oder
  192.                        -1000 für 'zu wenig daten geschrieben bei fwrite'
  193. */
  194. int do_store_img(char *name,MFDB *buffer,int wid,int hght,COLOR *col,int xflag)
  195. {
  196. char *line;
  197. static char lline[MAX_LINE_LEN],unpacked[256];
  198. static char buf[BUF_SIZE];
  199. static IMG_HEAD header;
  200. static SAVE_IMG img;
  201. int cnt,len,i;
  202. char *h;
  203.  
  204.     if ( h_error((long)(f_id=Fcreate(name,0)),0L) )
  205.         return xerr;
  206.  
  207.     init_write(buf);    /* init für write_byte */
  208.  
  209.     line=lline;
  210.  
  211.     init_img(&img,&header,buffer,wid,hght,line,MAX_LINE_LEN);
  212.  
  213.  
  214.     /*
  215.         header modifizieren für ximg
  216.     */
  217.     if ( xflag )
  218.         header.head_len+=3+3*(1<<header.plane_num);
  219.  
  220.     /*
  221.         header schreiben
  222.     */
  223.     for ( h=(char*)&header,len=0; len<16; len++,h++ )
  224.         if ( write_byte(*h) )
  225.             { Fclose(f_id); return xerr; }
  226.  
  227.  
  228.     /*
  229.         ximg schreiben
  230.     */
  231.     if ( xflag ) {
  232.         if ( write_byte('X') || write_byte('I') || write_byte('M') || write_byte('G')
  233.                 || write_byte(0) || write_byte(0) )
  234.                 { Fclose(f_id); return xerr; }
  235.         len=(int)sizeof(COLOR)*(1<<header.plane_num);
  236.  
  237. #ifndef GEMDUMP
  238.         if ( col ) {
  239. #endif
  240.             for ( h=(char*)col; len>0; h++,len-- )
  241.                 if ( write_byte(*h) )
  242.                     { Fclose(f_id); return xerr; }
  243. #ifndef GEMDUMP
  244.         }
  245.         else {    /* farben nicht gesetzt -> via xbios holen */
  246.           COLOR col;
  247.           int i,c;
  248.             for ( i=0; i<(1<<buffer->fd_nplanes); i++ ) {
  249.                 c=Setcolor(i,-1);
  250.                 col.red=(((c>>8)&7)*1000)/7;
  251.                 col.green=(((c>>4)&7)*1000)/7;
  252.                 col.blue=((c&7)*1000)/7;
  253.                 for ( h=(char*)&col,len=(int)sizeof(COLOR); len>0; h++,len-- )
  254.                     if ( write_byte(*h) )
  255.                         { Fclose(f_id); return xerr; }
  256.             }
  257.         }
  258. #endif
  259.     }
  260.  
  261.     /*
  262.         schreibe graphikdaten
  263.     */
  264.     while ( get_line(&img,0) ) {
  265.         cnt=1;
  266.         while ( cnt<255 && get_line(&img,1) ) {        /* gleiche zeilen? */
  267.             cnt++;
  268.         }
  269.         if ( cnt>1 ) {                                /* zeilenwiederholung eintragen */
  270.             if ( write_byte(0) || write_byte(0) || write_byte(0xFF) || write_byte(cnt) )
  271.                 { Fclose(f_id); return xerr; }
  272.         }
  273.  
  274.         h=line;                                        /* zeile schreiben */
  275.         for ( i=0; i<img.planes; i++ ) {
  276.             for ( len=cnt=0; cnt<img.bwid; ) {
  277.                 if ( (*h==0 && *(h+1)==0) || (*h==0xFF && *(h+1)==0xFF) ) {
  278.                   char muster;                        /* solid run */
  279.                     if ( len ) {
  280.                         if ( write_upk(len,unpacked) )
  281.                             { Fclose(f_id); return xerr; }
  282.                     }
  283.                     len=0;
  284.                     muster=*h;
  285.                     while ( *h==muster && cnt<img.bwid && len<63 )
  286.                         len++,cnt++,h++;
  287.                     if ( muster!=0 )
  288.                         len|=128;
  289.                     if ( write_byte(len) )
  290.                         { Fclose(f_id); return xerr; }
  291.                     len=0;
  292.                 }
  293.                 else if ( cnt+5<img.bwid && *h==*(h+1) && *h==*(h+2) && *h==*(h+3) && *h==*(h+4) ) {
  294.                   char muster_lo,muster_hi;            /* pattern run */
  295.                   char *h1,*h2;
  296.                     if ( len ) {
  297.                         if ( write_upk(len,unpacked) )
  298.                             { Fclose(f_id); return xerr; }
  299.                     }
  300.                     len=0;
  301.                     h1=h;
  302.                     h2=h1+1;
  303.                     muster_lo=*h1;
  304.                     muster_hi=*h2;
  305.                     while ( *h1==muster_lo && *h2==muster_hi && cnt<img.bwid-1 && len<255 )
  306.                         len++,cnt+=2,h1+=2,h2+=2;
  307.                     if ( write_byte(0) || write_byte(len) || write_byte(muster_lo) || write_byte(muster_hi) )
  308.                         { Fclose(f_id); return xerr; }
  309.                     h=h1;
  310.                     len=0;
  311.                 }
  312.                 else {                                /* unpacked */
  313.                     unpacked[len++]=*h++;
  314.                     cnt++;
  315.                     if ( len==255 ) {
  316.                         if ( write_upk(len,unpacked) )
  317.                             { Fclose(f_id); return xerr; }
  318.                         len=0;
  319.                     }
  320.                 }
  321.             }
  322.             if ( len ) {
  323.                 if ( write_upk(len,unpacked) )
  324.                     { Fclose(f_id); return xerr; }
  325.             }
  326.         }
  327.     }
  328.  
  329.     if ( close_write() )
  330.         { return xerr; }
  331.     h_error((long)Fclose(f_id),0L);
  332.  
  333.     return 0;
  334. }
  335.  
  336. /*
  337.     erzeuge namen für screendump
  338.         scr_nr ist zähler für bildnummer
  339. */
  340. void make_name(char *name)
  341. {
  342. char *d,*s,nr[10];
  343.  
  344.     for ( d=name,s=inst.file; *s!=0; )    /* kopiere dump_file nach name */
  345.         *d++=*s++;
  346.     itoa(scr_nr,nr,10);    /* don't use sprintf here (exceeds prg-size) */
  347.     scr_nr++;
  348.     for ( s=nr; *s!=0; )                /* strcat nr an name */
  349.         *d++=*s++;
  350.     for ( s=".IMG"; *s!=0; )
  351.         *d++=*s++;
  352.     *d=0;
  353. }
  354.  
  355. #ifndef GEMDUMP                            /* verwaltet zugriff auf fullscreen */
  356.                                         /* mittels scr->fd_addr==0l */
  357.                                         /* liest parameter via XBIOS (Logbase) */
  358.                                         /* Vdiesc/LineA-Variable */
  359.                                         /* dx==0 -> fullscreen */
  360.                                         /* dy==0 -> fullscreen */
  361. int store_img(char *name,MFDB *scr,int dx,int dy,COLOR *col,int xflag)
  362. {
  363.     if ( scr->fd_addr==0l ) {
  364.         linea_init();
  365.         scr->fd_addr=Logbase();
  366.         scr->fd_wdwidth=Vdiesc->bytes_lin/2/Linea->v_planes;
  367.                                         /* notwendig für overscan (dann ungleich dx/16!!) */
  368.         scr->fd_w=Vdiesc->v_rez_hz;
  369.         scr->fd_h=Vdiesc->v_rez_vt;
  370.         scr->fd_nplanes=Linea->v_planes;
  371.         scr->fd_stand=0;                /* geräteformat */
  372.     }
  373.     if ( dx==0 )
  374.         dx=scr->fd_w;
  375.     if ( dy==0 )
  376.         dy=scr->fd_h;
  377.  
  378.     if ( do_store_img(name,scr,dx,dy,col,xflag) )
  379.         return xerr;
  380.  
  381.     return 0;
  382. }
  383.  
  384. void do_althelp(void)                    /* aufruf von althelp */
  385. {
  386. MFDB scr;
  387. char name[64];
  388.  
  389.     make_name(name);
  390.  
  391.     scr.fd_addr=0l;                        /* access screen */
  392.     store_img(name,&scr,0,0,0l,inst.ximg);
  393. }
  394. #endif
  395.  
  396.